package hgx.spring.cloud.lession.myhystrix;/**
 * Created by liujun on 2018/4/19.
 */

import hgx.spring.cloud.lession.myhystrix.exception.MyExceptionType;
import hgx.spring.cloud.lession.myhystrix.exception.MyHystrixHandlerException;

/**
 * @author Administrator
 * @create 2018-04-19 14:26
 */
public abstract class BaseMyHystrixCommand<R> implements MyHystrixCommand {

    @Override
    public R getCacheByKey(MyCommandKeyType commandKeyType) {
        return null;
    }

    private boolean isOpen(){
         return MyHystrixManager.getInsance().isOpen();
    }

    protected  boolean isCache(MyCommandKeyType commandKeyType){
        return MyHystrixManager.getInsance().isCache(commandKeyType);
    }

    private boolean isAllowRequest(){
        return MyHystrixManager.getInsance().isAllowRequest();
    }

    private void success(){
        MyHystrixManager.getInsance().updateFailCount(true);
    }

    private  void fail(){
       MyHystrixManager.getInsance().updateFailCount(false);
    }

    public Object handler(Object [] objs,MyCommandKeyType commandKeyType){

        boolean hadlerFlag=false;
        Object result=null;
        try {
            result=dipsose(objs,commandKeyType);
            hadlerFlag=true;
            return result;
        }catch (Exception e){
            if(e instanceof MyHystrixHandlerException){
                MyHystrixHandlerException ex= (MyHystrixHandlerException) e;
                switch (ex.getMyExceptionType()){
                    case Hanler_Fail:
                        System.out.println("----Hystrix 处理失败");
                        getFallback();
                        break;
                    case Time_Out:
                        System.out.println("----Hystrix 处理超时");
                        getFallback();
                        break;
                    case Hystrix_Open:
                        System.out.println("----Hystrix 断路器打开 ");
                        getFallback();
                        break;
                    case Max_RequestCount:
                        System.out.println("----Hystrix 超过最大请求数，不处理数据");
                        getFallback();
                        break;
                }
            }else{
                System.out.println("----Hystrix 不知道原因的异常");
            }
        }finally {
            if(hadlerFlag){
                success();
            }else{
                fail();
            }
        }
        return result;
    }

    /**
     * 模板方法
     * @param objs
     * @param commandKeyType
     * @return
     */
    private Object dipsose(Object [] objs,MyCommandKeyType commandKeyType){
        long startTime=System.currentTimeMillis();

        if(isOpen()){
            throw new MyHystrixHandlerException("断路器打开了", MyExceptionType.Hystrix_Open);
        }

        if(!isAllowRequest()){
            throw new MyHystrixHandlerException("超过最大访问量",MyExceptionType.Max_RequestCount);
        }

         Object result=run(objs,commandKeyType);
        int hadlerTime= (int) (System.currentTimeMillis() -startTime);
        if(hadlerTime > MyHystrixManager.Handler_Time_Out){
            throw new MyHystrixHandlerException("处理请求超时",MyExceptionType.Time_Out);
        }
        return  result;
    }

    protected abstract Object run(Object [] objs,MyCommandKeyType commandKeyType);

    protected Object getFallback() {
        throw new UnsupportedOperationException("No fallback available.");
    }
}
